/* 
 * File:   Module.h
 * Author: pkv
 *
 * Created on July 28, 2011, 9:15 PM
 * 
 * Represents a dynamically loadable software module that may contain C++ or 
 * Lua components.
 */

#ifndef MODULE_H
#define	MODULE_H

#ifdef _WIN32
    // Windows (x64 and x86)    
    #define MODULE_EXPORT __declspec( dllexport )
#else 
    // Mac OS or POSIX
    #define MODULE_EXPORT extern "C"
#endif

#include <string>

namespace Module
{
    class Definition
    {
    public:
        virtual void *registerFn(void *param) = 0;
        virtual void *unregisterFn(void *param) = 0;
        virtual std::string name() = 0;

        typedef void*(*RegisterFn)(void*);
        typedef void*(*UnregisterFn)(void*);
    };
    
}

#define MODULE( moduleName, regFn, unregFn ) \
void *(regFn)(void *); \
void *(unregFn)(void *); \
namespace Module { \
    class moduleName : public Definition { \
        inline void *registerFn(void *param) { return (regFn)(param); } \
        inline void *unregisterFn(void *param) { return (unregFn)(param); } \
        inline std::string name() { return #moduleName; } \
    }; \
} \
MODULE_EXPORT void *RegisterModule_##moduleName(void *param) { \
    Module::Definition::RegisterFn fn = &(regFn); \
    return fn(param); \
} \
MODULE_EXPORT void *UnregisterModule_##moduleName(void *param) { \
    Module::Definition::UnregisterFn fn = &(unregFn); \
    return fn(param); \
}

#endif	/* MODULE_H */

